package team.seekers.hula.island.islandUser.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.island.islandUser.dao.IslandUserDao;
import team.seekers.hula.island.islandUser.entity.dao.IslandUserDO;
import team.seekers.hula.island.islandUser.entity.dto.IslandUserBatchBindDTO;
import team.seekers.hula.island.islandUser.entity.dto.IslandUserManagePageDTO;
import team.seekers.hula.island.islandUser.entity.dto.IslandUserUpdateDTO;
import team.seekers.hula.island.islandUser.entity.vo.IslandUserManagePageVO;
import team.seekers.hula.island.islandUser.entity.vo.IslandUserPageListVO;
import team.seekers.hula.user.user.entity.dao.UserDO;
import team.seekers.hula.user.user.service.UserService;

import java.util.*;

@Service
public class IslandUserManageService {

    @Autowired
    private UserService userService;

    @Autowired
    private IslandUserDao islandUserDao;


    public PageResult<IslandUserManagePageVO> pageUser(IslandUserManagePageDTO queryDTO) {
        // 先条件过滤islandUser
        HashMap<String, IslandUserDO> map = new HashMap<>();
        LambdaQueryChainWrapper<IslandUserDO> islandUserQueryWrapper = islandUserDao.lambdaQuery();
        if(queryDTO.getRole() != null) {
            islandUserQueryWrapper.eq(IslandUserDO::getRole,queryDTO.getRole());
        }
        islandUserQueryWrapper.eq(IslandUserDO::getIslandId,queryDTO.getIslandId());
        List<String> userId = new ArrayList<>();
        List<IslandUserDO> list = islandUserQueryWrapper.list();
        if(list.size() == 0){
            return new PageResult<>();
        }
        for (IslandUserDO islandUserDO : list) {
            userId.add(islandUserDO.getUserId());
            map.put(islandUserDO.getUserId(),islandUserDO);
        }
        // user表查询用户信息
        LambdaQueryChainWrapper<UserDO> userWrapper = userService.lambdaQuery();
        List<IslandUserManagePageVO> resList = new ArrayList<>();
        Optional.of(queryDTO).map(IslandUserManagePageDTO::getNickname).ifPresent(nickName -> {
            userWrapper.likeRight(UserDO::getNickname,nickName);
        });
        Optional.of(queryDTO).map(IslandUserManagePageDTO::getTel).ifPresent(tel -> {
            userWrapper.likeRight(UserDO::getTel, tel);
        });
        if(userId.size()!=0){
            userWrapper.in(UserDO::getId,userId);
        }
        Page<UserDO> page = userWrapper.page(new Page<>(queryDTO.getPageNow(), queryDTO.getPageSize()));
        for (UserDO userDO : page.getRecords()) {
            IslandUserDO islandUserDO = map.get(userDO.getId());
            IslandUserManagePageVO build = IslandUserManagePageVO.builder().id(islandUserDO.getId())
                    .nickname(userDO.getNickname())
                    .role(islandUserDO.getRole())
                    .tel(userDO.getTel())
                    .islandId(islandUserDO.getIslandId())
                    .hulaCoin(islandUserDO.getHulaCoin())
                    .userId(userDO.getId())
                    .gmtCreate(islandUserDO.getGmtCreate()).build();
            resList.add(build);
        }
        return new PageResult<>(page.getTotal(),page.getSize(),resList);
    }


    public PageResult<IslandUserManagePageVO> pageNotIn(IslandUserManagePageDTO islandUserManagePageDTO) {
        // 先排除所有已经在浪屿里面的
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery().select(IslandUserDO::getUserId).eq(IslandUserDO::getIslandId, islandUserManagePageDTO.getIslandId()).list();
        ArrayList<String> joinedUserIds = new ArrayList<>();
        for (IslandUserDO islandUserDO : islandUserDOList) {
            joinedUserIds.add(islandUserDO.getUserId());
        }

        // 剩下的条件查询
        // user表查询用户信息
        LambdaQueryChainWrapper<UserDO> userWrapper = userService.lambdaQuery();
        List<IslandUserManagePageVO> resList = new ArrayList<>();
        Optional.of(islandUserManagePageDTO).map(IslandUserManagePageDTO::getRole).ifPresent(role -> {
            userWrapper.eq(UserDO::getRole,role);
        });
        Optional.of(islandUserManagePageDTO).map(IslandUserManagePageDTO::getNickname).ifPresent(nickname -> {
            userWrapper.likeRight(UserDO::getNickname,nickname);
        });
        Optional.of(islandUserManagePageDTO).map(IslandUserManagePageDTO::getTel).ifPresent(tel -> {
            userWrapper.likeRight(UserDO::getTel, tel);
        });
        if(joinedUserIds.size()!=0){
            userWrapper.notIn(UserDO::getId,joinedUserIds);
        }
        Page<UserDO> page = userWrapper.page(new Page<>(islandUserManagePageDTO.getPageNow(), islandUserManagePageDTO.getPageSize()));
        for (UserDO userDO : page.getRecords()) {
            IslandUserManagePageVO build = IslandUserManagePageVO.builder()
                    .nickname(userDO.getNickname())
                    .role(userDO.getRole().getValue())
                    .tel(userDO.getTel())
                    .userId(userDO.getId())
                    .gmtCreate(userDO.getGmtCreate()).build();
            resList.add(build);
        }
        return new PageResult<>(page.getTotal(),page.getSize(),resList);

    }


    @Transactional
    public void updateRole(IslandUserUpdateDTO islandUserUpdateDTO) {
        IslandUserDO islandUserDO = new IslandUserDO();
        islandUserDO.setId(islandUserUpdateDTO.getId());
        islandUserDO.setRole(islandUserUpdateDTO.getRole());
        islandUserDao.updateById(islandUserDO);
    }

    @Transactional
    public void batchBind(IslandUserBatchBindDTO islandUserBatchBindDTO) {
        List<IslandUserDO> islandUserDOS = new ArrayList<>();
        for (String islandId : islandUserBatchBindDTO.getIslandIds()) {
            for (String userId : islandUserBatchBindDTO.getUserIds()) {
                IslandUserDO islandUserDO = new IslandUserDO();
                islandUserDO.setIslandId(islandId);
                islandUserDO.setUserId(userId);
                islandUserDO.setRole(islandUserBatchBindDTO.getRole());
                islandUserDOS.add(islandUserDO);
            }

            // 去重
            List<IslandUserDO> exists = islandUserDao.lambdaQuery()
                    .in(IslandUserDO::getUserId, islandUserBatchBindDTO.getUserIds())
                    .eq(IslandUserDO::getIslandId, islandId).list();
            islandUserDOS.removeAll(exists);
        }
        islandUserDao.saveOrUpdateBatch(islandUserDOS);
    }

    @Transactional
    public void unbind(String userId, String islandId) {
        LambdaQueryWrapper<IslandUserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IslandUserDO::getUserId, userId);
        queryWrapper.eq(IslandUserDO::getIslandId, islandId);
        islandUserDao.remove(queryWrapper);
    }


    /**
     * 查询已购买数量
     */
    public Integer countBuy(String id) {
        return islandUserDao.lambdaQuery().eq(IslandUserDO::getIslandId,id).count();
    }

    /**
     * 查询已常驻数量
     */
    public Integer countFixed(String id) {
        return islandUserDao.lambdaQuery().eq(IslandUserDO::getIslandId,id).eq(IslandUserDO::getIsFixed,1).count();
    }

    /**
     * 改变记忆浪屿的剩余刻入数量
     */
    public void changeCount(String islandId, String userId, int count) {
        IslandUserDO islandUserDO = islandUserDao.lambdaQuery()
                .select(IslandUserDO::getCount,IslandUserDO::getId)
                .eq(IslandUserDO::getIslandId, islandId)
                .eq(IslandUserDO::getUserId, userId)
                .one();
        islandUserDO.setCount(islandUserDO.getCount()+count);
        islandUserDao.updateById(islandUserDO);
    }

    public List<String> getFixedIslandIds(String userId) {
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery()
                .select(IslandUserDO::getIslandId)
                .eq(IslandUserDO::getIsFixed, 1)
                .eq(IslandUserDO::getUserId, userId)
                .list();

        ArrayList<String> islandIds = new ArrayList<>();
        for (IslandUserDO islandUserDO : islandUserDOList) {
            islandIds.add(islandUserDO.getIslandId());
        }
        return islandIds;
    }

    public List<String> getIslandIds(String userId) {
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery()
                .select(IslandUserDO::getIslandId)
                .eq(IslandUserDO::getUserId, userId)
                .list();

        ArrayList<String> islandIds = new ArrayList<>();
        for (IslandUserDO islandUserDO : islandUserDOList) {
            islandIds.add(islandUserDO.getIslandId());
        }
        return islandIds;
    }

    public Map<String, IslandUserManagePageVO> mapIslandIdsAndJoinStatus(ArrayList<String> islandIds, String userId) {
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery()
                .select()
                .eq(IslandUserDO::getUserId, userId)
                .in(IslandUserDO::getIslandId, islandIds)
                .list();

        HashMap<String, IslandUserManagePageVO> map = new HashMap<>();

        for (IslandUserDO record : islandUserDOList) {
            UserDO userDO = userService.getById(record.getUserId());
            IslandUserManagePageVO build = IslandUserManagePageVO.builder()
                    .nickname(userDO.getNickname())
                    .role(record.getRole())
                    .tel(userDO.getTel())
                    .userId(record.getId())
                    .hulaCoin(record.getHulaCoin())
                    .gmtCreate(record.getGmtCreate()).build();
            map.put(record.getIslandId(),build);
        }
        return map;
    }
}
